package ch.janotta.slawo.ultraquest.types;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Character {
  private static final Logger LOGGER = LoggerFactory.getLogger(Character.class);

  private String name;
  private Species species;
  private Gender gender;
  private Profession profession;
  private List<Area> nativeAreas;
  private int speed;
  private int strength;
  private int dexterity;
  private int intelligence;
  private List<Item> carriedItems;
  private List<Item> backpackItems;
  private int gold;
  private RidingMount mount;

  public Character() {
    nativeAreas = new ArrayList<Area>();
    carriedItems = new ArrayList<Item>();
    backpackItems = new ArrayList<Item>();
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Species getSpecies() {
    return species;
  }

  public void setSpecies(Species species) {
    this.species = species;
  }

  public Gender getGender() {
    return gender;
  }

  public void setGender(Gender gender) {
    this.gender = gender;
  }

  public Profession getProfession() {
    return profession;
  }

  public void setProfession(Profession profession) {
    this.profession = profession;
  }

  public List<Area> getNativeAreas() {
    return nativeAreas;
  }

  public void setNativeAreas(List<Area> nativeAreas) {
    this.nativeAreas = nativeAreas;
  }

  public void addNativeArea(Area area) {
    if (!this.nativeAreas.contains(area)) {
      this.nativeAreas.add(area);
    } else {
      LOGGER.debug("Character {} already native in {}", this.name, area.name());
    }
  }

  public int getSpeed() {
    return speed;
  }

  public void setSpeed(int speed) {
    this.speed = speed;
  }

  public int getStrength() {
    return strength;
  }

  public void setStrength(int strength) {
    this.strength = strength;
  }

  public int getDexterity() {
    return dexterity;
  }

  public void setDexterity(int dexterity) {
    this.dexterity = dexterity;
  }

  public int getIntelligence() {
    return intelligence;
  }

  public void setIntelligence(int intelligence) {
    this.intelligence = intelligence;
  }

  public List<Item> getCarriedItems() {
    return carriedItems;
  }

  public void setCarriedItems(List<Item> carriedItems) {
    this.carriedItems = carriedItems;
  }

  public void removeCarriedItem(Item item) {
    if (this.carriedItems.contains(item)) {
      this.carriedItems.remove(item);
    } else {
      LOGGER.error("Item {} not carried", item.getName());
    }
  }

  public void addCarriedItem(Item item) {
    if (!this.carriedItems.contains(item)) {
      this.carriedItems.add(item);
    } else {
      LOGGER.warn("Item {} already carried", item.getName());
    }
  }

  public List<Item> getBackpackItems() {
    return backpackItems;
  }

  public void setBackpackItems(List<Item> backpackItems) {
    this.backpackItems = backpackItems;
  }

  public void removeBackpackItem(Item item) {
    if (this.backpackItems.contains(item)) {
      this.backpackItems.remove(item);
    } else {
      LOGGER.error("Item {} not in backpack", item.getName());
    }
  }

  public void addBackpackItem(Item item) {
    if (!this.backpackItems.contains(item)) {
      this.backpackItems.add(item);
    } else {
      LOGGER.warn("Item {} already in backpack", item.getName());
    }
  }

  public int getGold() {
    return gold;
  }

  public void setGold(int gold) {
    this.gold = gold;
  }

  public void addGold(int value) {
    gold += value;
  }

  public void subtractGold(int value) {
    if (gold >= value) {
      gold -= value;
    } else {
      LOGGER.error("Not enough gold in purse");
    }
  }

  public RidingMount getRidingMount() {
    return mount;
  }

  public void setRidingMount(RidingMount mount) {
    this.mount = mount;
  }

  public int getMaxCloseCombatValue() {
    int maxCloseCombatValue = 0;
    for (Item item: carriedItems) {
      if (item.getCloseCombatValue() > maxCloseCombatValue) {
        maxCloseCombatValue = item.getCloseCombatValue();
      }
    }
    return maxCloseCombatValue;
  }

  public int getMaxRangedCombatValue() {
    int maxRangedCombatValue = 0;
    for (Item item: carriedItems) {
      if (item.getRangedCombatValue() > maxRangedCombatValue) {
        maxRangedCombatValue = item.getRangedCombatValue();
      }
    }
    return maxRangedCombatValue;
  }

  public int getMaxCombinedCombatValue() {
    int maxCombinedCombatValue = 0;
    for (Item item: carriedItems) {
      if (item.getCloseCombatValue() > maxCombinedCombatValue) {
        maxCombinedCombatValue = item.getCloseCombatValue();
      }
      if (item.getRangedCombatValue() > maxCombinedCombatValue) {
        maxCombinedCombatValue = item.getRangedCombatValue();
      }
    }
    return maxCombinedCombatValue;
  }
}
